package client;

import javax.swing.*;

import common.JobObject;
import common.JobsPackage;

import java.awt.*;
import java.awt.event.*;
import java.awt.Dimension;
import java.io.File;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;

import client.ClientManageGUI;
import java.util.regex.Pattern;

/*class ClientManageGUI extends JFrame implements ActionListener
{
	JButton RETRIVEERESULT;
	JPanel panel1,panel2;
	JLabel label1,label2,label3,label4,label5,label6,label7,label8;
	String numJob,numCompletedJob,numRunningJob,numWaitingJob;
	final JTextField  serverAdd,serverPort;
	public ClientManageUI()
	{
		label1 = new JLabel();
		label1.setText("Total number of Jobs:");
		//serverAdd = new JTextField(32);
		
		label2 = new JLabel();
		label2.setText("Total number of completed Jobs:");
		//serverPort = new JTextField(4);
		
		label3 = new JLabel();
		label3.setText("Total number of running Jobs:");
		//serverAdd = new JTextField(32);
		
		label4 = new JLabel();
		label4.setText("Total number of waiting Jobs:");
		//serverPort = new JTextField(4);
		
		label5 = new JLabel();
		label5.setText(numJob);
		//serverAdd = new JTextField(32);
		
		label6 = new JLabel();
		label6.setText(numCompletedJob);
		//serverPort = new JTextField(4);
		
		label7 = new JLabel();
		label7.setText(numRunningJob);
		//serverAdd = new JTextField(32);
		
		label8 = new JLabel();
		label8.setText(numWaitingJob);
		//serverPort = new JTextField(4);
		
		RETRIVEERESULT = new JButton("Retrieve Results");
		
		panel1=new JPanel(new GridLayout(4,2));
		panel1.add(label1);
		panel1.add(label2);
		panel1.add(label3);
		panel1.add(label4);
		panel1.add(label5);
		panel1.add(label6);
		panel1.add(label7);
		panel1.add(label8);

		add(panel1,BorderLayout.CENTER);
		
		
		
		
		
		//panel.add(serverPort);
		panel2.add(RETRIVEERESULT);
		
		//CONNECT.addActionListener(this);
		//serverPort.addActionListener(this);
		//serverAdd.addActionListener(this);
		
		setTitle("Manage");
		setSize(400, 150);
		
	
		initialize();
	}*/
	
	/**
	 * This method initializes this
	 * 
	 */
	/*private void initialize() {
			
	}


	public void actionPerformed(ActionEvent ae)
	{
		Client client = new Client();
		try {
			if(client.GUIconnect(serverAdd.getText(), Integer.parseInt(serverPort.getText()))) {
				IssueJobGUI jobissue = new IssueJobGUI(client);
				jobissue.setVisible(true);
				this.setVisible(false);
			}
			else {
				JOptionPane.showMessageDialog(null, "Error connecting to Server");
			}
		} catch (Exception e) {
			JOptionPane.showMessageDialog(null, "Error: " + e.getMessage());
		}
		
	}
}*/

 
class ClientConnectGUI extends JFrame implements ActionListener
{
	//JButton CONNECT;
	JButton sendJob,manageJob;
	JPanel panel;
	JLabel label1,label2,label3;
	final JTextField  serverAdd,serverPort,clientRevPort;
	public ClientConnectGUI()
	{
		label1 = new JLabel();
		label1.setText("Server Address:");
		serverAdd = new JTextField(32);
		
		label2 = new JLabel();
		label2.setText("Port:");
		serverPort = new JTextField(4);
		
		label3 = new JLabel();
		label3.setText("Listen Port:");
		clientRevPort = new JTextField(4);
		
		//CONNECT=new JButton("Connect");
		sendJob = new JButton("Send Jobs");
		manageJob = new JButton("Manage Jobs");
		
		GridLayout grid = new GridLayout(0,2);
		grid.setHgap(5);
		grid.setVgap(5);
		panel=new JPanel(grid);
		panel.add(label1);
		panel.add(serverAdd);
		panel.add(label2);
		panel.add(serverPort);
		panel.add(label3);
		panel.add(clientRevPort);
		panel.add(sendJob);
		panel.add(manageJob);
		//panel.add(CONNECT);
		
		
		
		//CONNECT.addActionListener(this);
		
		sendJob.addActionListener(this);
		sendJob.setActionCommand("sendJob");
		
		manageJob.addActionListener(this);
		manageJob.setActionCommand("manageJob");
		
		serverPort.addActionListener(this);
		serverAdd.addActionListener(this);
		
		add(panel,BorderLayout.CENTER);
		setTitle("Cloud Server Client");
		setSize(400, 150);
		
	    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 */
	private void initialize() {
			
	}


	public void actionPerformed(ActionEvent ae)
	{
		//Client client = new Client();
		try {
			
			if ("sendJob".equals(ae.getActionCommand()))
			{
				IssueJobGUI jobissue = new IssueJobGUI(serverAdd.getText(), Integer.parseInt(serverPort.getText()), Integer.parseInt(clientRevPort.getText()));
				jobissue.setVisible(true);
				this.setVisible(false);
			}
			/*else {
				JOptionPane.showMessageDialog(null, "Error connecting to Server");
			}
			}*/
			else if("manageJob".equals(ae.getActionCommand()))
			{
				   ManageRequestGUI manageRequestGUI = new ManageRequestGUI(serverAdd.getText(), Integer.parseInt(serverPort.getText()), Integer.parseInt(clientRevPort.getText()));
				   manageRequestGUI.setVisible(true);
				   this.setVisible(false);
				
				/*else{
					JOptionPane.showMessageDialog(null, "Error connecting to Server");
				}*/
			}
		} catch (Exception e) {
			JOptionPane.showMessageDialog(null, "Error: " + e.getMessage());
		}
		
	}
}

class IssueJobGUI extends JFrame implements ActionListener
{
	JFileChooser fc;
	JButton ADD, START, Open, AddFile;
	JRadioButton TIME, COST, HIGH, LOW;
	JPanel panel;
	JLabel padlabel, padlabel1, pathLabel, fileLabel, parameterLabel, timeLabel, jobNoLabel, deadlineLabel, budgetLabel;
	final JTextField  executeFile, parameters, executeTime, deadline, budget;
	int jobID, priority,serverPort;
	Client client;
	String type, strExecutePath, strExecuteFile,serverAdd;
	public IssueJobGUI(String serverAdd, int serverPort, int clientRevPort)
	{
		client = new Client();
		this.serverAdd = serverAdd;
		this.serverPort = serverPort;
		
		System.out.println("DEBUG - Server Address:" + this.serverAdd);
		System.out.println("DEBUG - Server Port:" + this.serverPort);
		this.client.GUIconnect(serverAdd, serverPort, clientRevPort);
		
		jobID = 0;
		priority = 0;
		type = "TIME";
		strExecutePath = null;
		strExecuteFile = null;
		padlabel = new JLabel();
		padlabel1 = new JLabel();
		
		fc = new JFileChooser();
		Open = new JButton("Open");
		Open.addActionListener(this);
		Open.setActionCommand("Open");
		
		AddFile = new JButton("Add Data File");
		AddFile.addActionListener(this);
		AddFile.setActionCommand("AddFile");
		
		//pathLabel = new JLabel();
		//pathLabel.setText("Execute file path:");
		//executePath = new JTextField(32);
		//executePath.setActionCommand("ADD");
		//executePath.addActionListener(this);
		
		fileLabel = new JLabel();
		fileLabel.setText("Execute file:");
		executeFile = new JTextField(32);
		
		parameterLabel = new JLabel();
		parameterLabel.setText("Parameters:");
		parameters = new JTextField(4);
		
		timeLabel = new JLabel();
		timeLabel.setText("Execution time in seconds:");
		executeTime = new JTextField(4);
		
		//priorityLabel = new JLabel();
		//priorityLabel.setText("Priority:");
		//priority = new JTextField(4);
		
		deadlineLabel = new JLabel();
		deadlineLabel.setText("Deadline in seconds:");
		deadline = new JTextField(4);
		
		budgetLabel = new JLabel();
		budgetLabel.setText("Budget:");
		budget = new JTextField(4);
		
		TIME=new JRadioButton("Optimize Time");
		TIME.addActionListener(this);
		TIME.setActionCommand("TIME");
		
		COST=new JRadioButton("Optimize Cost");
		COST.addActionListener(this);
		COST.setActionCommand("COST");
		
		HIGH=new JRadioButton("High Priority");
		HIGH.addActionListener(this);
		HIGH.setActionCommand("HIGH");
		
		LOW=new JRadioButton("Low Priority");
		LOW.addActionListener(this);
		LOW.setActionCommand("LOW");
		
		jobNoLabel = new JLabel();
		
		ADD=new JButton("Add");
		ADD.addActionListener(this);
		ADD.setActionCommand("ADD");
		START=new JButton("Start");
		START.addActionListener(this);
		START.setActionCommand("START");
		
		GridLayout grid = new GridLayout(0,2);
		grid.setHgap(5);
		grid.setVgap(5);
		panel=new JPanel(grid);
		panel.add(fileLabel);
		panel.add(executeFile);
		panel.add(padlabel);
		panel.add(Open);
		panel.add(parameterLabel);
		panel.add(parameters);
		panel.add(timeLabel);
		panel.add(executeTime);
		panel.add(LOW);
		panel.add(HIGH);
		panel.add(jobNoLabel);
		panel.add(ADD);
		panel.add(deadlineLabel);
		panel.add(deadline);
		panel.add(budgetLabel);
		panel.add(budget);
		panel.add(TIME);
		panel.add(COST);
		panel.add(padlabel1);
		panel.add(START);
		add(panel,BorderLayout.CENTER);
		setTitle("Cloud Server Client");
		setSize(500, 400);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	public void actionPerformed(ActionEvent ae)
	{
		if ("Open".equals(ae.getActionCommand())) {
			int returnVal = fc.showOpenDialog(this);

            if (returnVal == JFileChooser.APPROVE_OPTION) {
                File file = fc.getSelectedFile();
                executeFile.setText(file.getAbsolutePath());
            }
		}
		else if ("ADD".equals(ae.getActionCommand())) {
//            if (!executeFile.getText().equals("")&& isDotClass(executeFile.getText())) {
//                strExecutePath = executeFile.getText().substring(0, executeFile.getText().lastIndexOf('\\') + 1);
//                    strExecuteFile = executeFile.getText().substring(executeFile.getText().lastIndexOf('\\') + 1, executeFile.getText().lastIndexOf(".class"));
//                    System.out.println(strExecuteFile);
//                    System.out.println(strExecutePath);
//            } else {
//                JOptionPane.showMessageDialog(null, "Invalid Input");
//            }
            if (parameters.getText().equals("") || executeTime.getText().equals("") || (!isNumber(executeTime.getText()))||executeFile.getText().equals("")||(!isDotClass(executeFile.getText()))) {
                JOptionPane.showMessageDialog(null, "Invalid Input");
            } else {
                strExecutePath = executeFile.getText().substring(0, executeFile.getText().lastIndexOf('\\') + 1);
                    strExecuteFile = executeFile.getText().substring(executeFile.getText().lastIndexOf('\\') + 1, executeFile.getText().lastIndexOf(".class"));
                    System.out.println(strExecuteFile);
                    System.out.println(strExecutePath);  
                
                client.GUIIssueJob(strExecutePath, strExecuteFile, parameters.getText(), (Integer.parseInt(executeTime.getText())), jobID++, priority);
                jobNoLabel.setText("Number of jobs: " + jobID);
                clearTextFields();
            }
		}
		else if ("TIME".equals(ae.getActionCommand())) {
			type = "TIME";
		}
		else if ("COST".equals(ae.getActionCommand())) {
			type = "COST";
		}
		else if ("HIGH".equals(ae.getActionCommand())) {
			priority = 1;
		}
		else if ("COST".equals(ae.getActionCommand())) {
			priority = 0;
		}
		else if ("START".equals(ae.getActionCommand())) {
			
			//System.out.println("DEBUG - ClientID:" + client.jp.get);
			 if (deadline.getText().equals("") || budget.getText().equals("")||(!isNumber(deadline.getText()))||(!isNumber(budget.getText()))) {
                 JOptionPane.showMessageDialog(null, "Invalid Input");
             } else {
                System.out.println("DEBUG - Server Address:" + this.serverAdd);
                this.client.GUIStartScheduling(deadline.getText(), budget.getText(), type);
                String info;
                if (client.clientID != null) {
                    info = "Send Job successfully. ClientID is " + client.clientID + ". Please record this ClientID to get result.";
                } else {
                    info = "Error: Can not send jobs.";
                }

                JOptionPane.showMessageDialog(null, info);
                ClientManageGUI clientManager = new ClientManageGUI(client);
                clientManager.setVisible(true);
                this.setVisible(false);
            }
			//Create new panel to display progress
		}
	}
	private void clearTextFields() {
		executeFile.setText("");
		parameters.setText("");
		executeTime.setText("");
	}

    private boolean isNumber(String str){
        Pattern pattern = Pattern.compile("-?[0-9]*(\\.)?[0-9]*");
        return pattern.matcher(str).matches();
    }
    private boolean isDotClass(String str){
        Pattern pattern = Pattern.compile(".*(\\.)class");
        return pattern.matcher(str).matches();
    }
}
/*
class IssueJobResultGUI extends JFrame implements ActionListener
{
	String Info;
	JPanel panel;
	JLabel label;
	JButton OK;
	Client client;
	public IssueJobResultGUI(Client client)
	{
		this.client = client;
		if(client.clientID!=null)
		{
			Info = "Send Job successfully. ClientID is " + client.clientID + ". Please record this ClientID to get result.";
		}
		else
		{
			Info = "Error: Can not send jobs.";
		}
		
		label = new JLabel();
		label.setText(Info);
		OK=new JButton("OK");
		OK.addActionListener(this);
		panel=new JPanel(new GridLayout(2,0));
		panel.add(label);
		panel.add(OK);
		add(panel,BorderLayout.CENTER);
		setTitle("Send Jobs Result");
		setSize(400, 100);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	@Override
	public void actionPerformed(ActionEvent arg0) {
		//client.setClientID(myClientID);
		ClientManageGUI clientManager = new ClientManageGUI(client);
		clientManager.setVisible(true);
		this.setVisible(false);
	}
}
*/

class ManageRequestGUI extends JFrame implements ActionListener
{
	JPanel panel;
	JButton Send;
	JLabel clientidLabel;
	Client client;
	String serverAdd;
	int serverPort, clientRevPort;
	final JTextField clientID;
	public ManageRequestGUI(String serverAdd, int serverPort, int clientRevPort)
	{
		this.serverAdd = serverAdd;
		this.serverPort = serverPort;
		this.clientRevPort = clientRevPort;
		clientidLabel = new JLabel();
		clientidLabel.setText("Please input Client ID to manage jobs:");
		
		clientID = new JTextField(10);
		
		Send = new JButton("Send");
		Send.addActionListener(this);
		
		panel=new JPanel(new GridLayout(3,1));
		
		panel.add(clientidLabel);
		panel.add(clientID);
		panel.add(Send);
		
		add(panel,BorderLayout.CENTER);
		setTitle("Client Request Manage");
		setSize(400, 150);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
	}
	
	public void actionPerformed(ActionEvent e)
	{
		this.setVisible(false);	
		
		client = new Client();
		
		//client.GUIconnect(serverAdd, serverPort);
		client.setClientID(clientID.getText());
		client.setClientRevPort(clientRevPort);
		try {
	    	InetAddress serverIP = null;
			serverIP = InetAddress.getByName(serverAdd);
	    	
			client.QueryJobs(clientID.getText(),serverIP,serverPort);
		} catch (UnknownHostException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		
		ClientManageGUI clientManageGUI = new ClientManageGUI(client);
		clientManageGUI.setVisible(true);
		ListenNotify listenNotify = new ListenNotify(clientRevPort);
		listenNotify.start();
	}
}



/*class RetrieveResultGUI extends JFrame implements ActionListener
{
	String Info;
	JPanel panel;
	JLabel label;
	JButton OK;
	Client client;
	public RetrieveResultGUI(JobsPackage jobspackage)
	{
		this.client = client;
		if(client.clientID!=null)
		{
			Info = "Send Job successfully. ClientID is " + client.clientID + ". Please record this ClientID to get result.";
		}
		else
		{
			Info = "Error: Can not send jobs.";
		}
		
		label = new JLabel();
		label.setText(Info);
		OK=new JButton("OK");
		OK.addActionListener(this);
		panel=new JPanel(new GridLayout(2,0));
		panel.add(label);
		panel.add(OK);
		add(panel,BorderLayout.CENTER);
		setTitle("Send Jobs Result");
		setSize(400, 100);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	@Override
	public void actionPerformed(ActionEvent arg0) {
		//client.setClientID(myClientID);
		ClientManageGUI clientManager = new ClientManageGUI(client);
		clientManager.setVisible(true);
		this.setVisible(false);
	}
}*/

	
public class ClientGUI {
	public static void main(String arg[])
	{
		try
		{
			//ClientConnectGUI frame=new ClientConnectGUI();
			ClientConnectGUI serverConnect = new ClientConnectGUI();
			serverConnect.setName("Server Connect");
			serverConnect.setVisible(true);
		}
		catch(Exception e){
			JOptionPane.showMessageDialog(null, e.getMessage());
		}
	}
}